<!--
 * @Description:
 * @Author: IA ia@kepro.space
 * @Date: 2025-02-20 00:05:49
-->
<template>
  <div>
    <h1>第二十七章（自定义指令directive）图片懒加载</h1>
    <div class="imgBox">
      <!-- <img v-for="item in arr" :src="item" alt="" width="360" height="500" /> -->
      <img v-lazy="item" v-for="item in arr" alt="" width="360" height="480" />
    </div>
  </div>
</template>
<script setup lang="ts">
import type { Directive, DirectiveBinding } from 'vue'

// glob 是懒加载模式，类似于
// let modules = {
//   xxx: () => import('xxx'),
// }
// globEager是静态加载，类似于
// import xxx from 'xxx'

let imageListWithoutEager = import.meta.glob('@/assets/images/*.*')
let imageList: Record<string, { default: string }> = import.meta.glob('@/assets/images/*.*', {
  eager: true,
})

console.log('imageListWithoutEager: ', imageListWithoutEager)
console.log('imageList: ', imageList)

const arr = Object.values(imageList).map((v) => v.default)

console.log('arr: ', arr)

let vLazy: Directive<HTMLImageElement, string> = async (el, binding) => {
  console.log('el: ', el)
  const def = await import('@/assets/logo.svg')
  el.src = def.default
  // 判断元素是否在可视区域
  const observer = new IntersectionObserver((entries) => {
    /*
      IntersectionObserver的IntersectionObserverEntry 有6个树型
      boundingClientRect：目标元素的矩形区域的细腻系
      intersectionRatio: 目前元素可见比例，即 intersectionRect 占 boundingClientRect 的比例，完成可见时为 1 ，完全不可以时小于等于 0
      intersectionRect: 目标元素与视口（或容器元素）的交叉区域的信息
      rootBounds: 容器元素的矩形区域的信息， getBoundingClientRect() 方法的返回值，如果没有容器元素（即直接相对于视口滚动），则返回null
      target: 被观察的目标元素，是一个DOM节点对象
      time: 可见性发生变化的事件，是一个高精度时间戳，单位为毫秒
      isIntersecting:
      isVisible:
    */
    console.log('IntersectionObserver entries: ', entries, 'binding: ', binding.value)

    if (entries[0].intersectionRatio > 0) {
      setTimeout(() => {
        el.src = binding.value
        observer.unobserve(el)
      }, 1000)
    }
  })
  observer.observe(el)
}
</script>
<style scoped lang="less">
h1,
h2,
h3,
hr {
  margin: 10px 0;
}

.imgBox {
  width: 360px;
  height: 100%;
  display: flex;
  flex-direction: column;

  img {
    margin-bottom: 5px;
  }
}
</style>
